package com.lots.service.impl;

import com.lots.context.BaseContext;
import com.lots.domain.dto.FavoriteDto;
import com.lots.domain.dto.LoginDto;
import com.lots.domain.dto.RegisterDto;
import com.lots.domain.entity.Dish;
import com.lots.domain.entity.User;
import com.lots.domain.entity.UserFavorite;
import com.lots.domain.vo.LoginInfo;
import com.lots.mapper.DishDetailMapper;
import com.lots.mapper.DishMapper;
import com.lots.mapper.UserFavoriteMapper;
import com.lots.mapper.UserMapper;
import com.lots.properties.JwtProperties;
import com.lots.service.UserService;
import com.lots.utils.JwtUtil;
import com.lots.utils.PasswordUtil;
import com.lots.utils.RedisUtil;
import com.lots.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.net.http.WebSocket;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class UserServiceImpl implements UserService {
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserFavoriteMapper userFavoriteMapper;
    @Autowired
    private DishDetailMapper dishDetailMapper;


    /**
     * 登录
     *
     * @param user
     * @return
     */
    @Override
    public LoginInfo login(LoginDto user) {
        String password = user.getPassword();
        //前端的密码加密后在数据库匹配
        user.setPassword(PasswordUtil.encodePassword(password));
        User userInfo = userMapper.login(user);
        if (userInfo == null) {
            log.info("用户不存在");
            return null;
        }
        LoginInfo loginInfo = new LoginInfo();

        //1.生成token
        HashMap<String, Object> claims = new HashMap<>();
        claims.put("userId", userInfo.getId());
        String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
        //2.封装数据
        loginInfo.setToken(token);
        loginInfo.setId(userInfo.getId());
        loginInfo.setName(userInfo.getName());
        loginInfo.setAvatar(userInfo.getAvatar());
        loginInfo.setPhone(userInfo.getPhone());
        return loginInfo;
    }

    /**
     * 获取验证码
     *
     * @param phone
     */
    @Override
    public void code(String phone) {

        String code = (int) ((Math.random() * 9 + 1) * 100000) + "";
        // 存入redis 验证码 5分钟有效
        log.info("发送验证码成功:{}", code);
        redisUtil.set("code:" + phone, code, 300);

        // 直接拼接短信内容
        String content = "【Lots】手机验证码:" + code + "，用于手机验证码登录，5分钟内有效。"
                + "验证码提供给他人可能导致账号被盗，请勿泄露，谨防被骗。";
        // WebSocket 发送
        // 延迟 2 秒发送，不阻塞接口
        scheduler.schedule(() -> {
            boolean sent = WebSocketServer.sendToClient(phone, content);
            if (!sent) {
                log.warn("通过 WebSocket 发送验证码失败，目标未连接或发送异常，phone={}", phone);
            } else {
                log.info("验证码已通过 WebSocket 发送，phone={}", phone);
            }
        }, 2, TimeUnit.SECONDS);

    }


    /**
     * 注册
     *
     * @param registerDto
     * @return
     */
    @Override
    public Integer register(RegisterDto registerDto) {
        User user = userMapper.selectByPhone(registerDto.getPhone());
        if (user != null) {
            log.info("用户已存在");
            return -1;
        }
        String redisCod = null;
        redisCod = (String) redisUtil.get("code:" + registerDto.getPhone());
        if (redisCod == null || redisCod.isEmpty()) {
            log.info("验证码已过期");
            return -2;
        }
        if (redisCod.equals(registerDto.getCode())) {
            //注册成功将用户信息存入数据库
            user = new User();
            user.setName("用户" + registerDto.getPhone().substring(registerDto.getPhone().length() - 4));
            user.setAvatar("https://java-ai177.oss-cn-beijing.aliyuncs.com/dog.jpg");
            //密码加密储存
            user.setPassword(PasswordUtil.encodePassword(registerDto.getPassword()));
            user.setPhone(registerDto.getPhone());
            log.info("注册成功");
            userMapper.insert(user);
            return 1;
        }
        return 0;
    }

    /**
     * 添加收藏
     *
     * @param favoriteDto
     */
    @Transactional
    @Override
    public void favorite(FavoriteDto favoriteDto) {
        int userFavorite = userFavoriteMapper.queryFavorite(favoriteDto.getUserId(), favoriteDto.getDishId());
        //没查到数据就是点赞
        if (userFavorite == 0) {
            UserFavorite userFavorite1 = new UserFavorite();
            userFavorite1.setUserId(favoriteDto.getUserId());
            userFavorite1.setDishId(favoriteDto.getDishId());
            dishMapper.updateStar(favoriteDto.getDishId(), 1);
            userFavoriteMapper.insertFavorite(userFavorite1);

        } else {
            //反之就是取消点赞
            dishMapper.updateStar(favoriteDto.getDishId(), -1);
            userFavoriteMapper.deleteFavorite(favoriteDto.getUserId(), favoriteDto.getDishId());
        }
    }

    /**
     * 查询用户作品
     *
     * @return
     */
    @Override
    public List<Dish> queryWorks() {
        Long userId = BaseContext.getCurrentId();
        List<Long> dishIds = dishDetailMapper.queryWorks(userId);
       return dishMapper.queryByIds(dishIds);
    }

    /**
     * 查询收藏
     *
     * @return
     */
    @Override
    public List<Dish> queryStars() {
        Long userId = BaseContext.getCurrentId();
        List<Long> favoriteList = userMapper.queryStars(userId);
        //根据菜品id批量查询菜品
        return dishMapper.queryStars(favoriteList);
    }

    @Override
    public void updateAvatar(Long userId, String avatar) {
            userMapper.updateAvatar(userId,avatar);
    }

    @Override
    public void updateUserName(Long userId, String name) {
        userMapper.updateUserName(userId,name);
    }
}
